package com.base.monitor.module.biz.service.cfg.impl;

import com.base.monitor.framework.exception.CustomerException;
import com.base.monitor.framework.properties.SystemProperties;
import com.base.monitor.framework.util.DiskUtils;
import com.base.monitor.framework.util.IpUtils;
import com.base.monitor.model.constant.CommonConstant;
import com.base.monitor.model.enums.code.impl.server.ServerCode;
import com.base.monitor.module.biz.component.RefreshComponent;
import com.base.monitor.module.biz.context.ClientContext;
import com.base.monitor.module.biz.server.TcpServer;
import com.base.monitor.module.biz.properties.NetworkProperties;
import com.base.monitor.module.biz.service.cfg.ServerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.stereotype.Service;

@Service
@EnableConfigurationProperties(SystemProperties.class)
public class ServerServiceImpl implements ServerService {

    @Autowired
    private NetworkProperties networkProperties;

    @Autowired
    private DiskUtils diskUtils;

    @Autowired
    private RefreshComponent refreshComponent;

    /**
     * 修改端口号
     * @param port 端口号
     */
    @Override
    public void changeServerPort(Integer port) {
        // 1.校验端口号
        validatePort(port);

        // 2.修改配置文件中的端口号值
        diskUtils.updatePropertiesFile("network.port", port + "");

        // 3.修改端口号
        networkProperties.setPort(port);

        // 4.重启
        refreshComponent.restart();

        // 5.初始化客户端列表
        ClientContext.getClientMap().clear();
    }

    /**
     * 校验端口号
     * @param port 端口号
     */
    private void validatePort(Integer port) {
        if (port == null || port > CommonConstant.MAX_PORT || port < CommonConstant.MIN_PORT) {
            throw new CustomerException(ServerCode.ILLEGAL_PORT);
        }
        if (networkProperties.getPort().equals(port)) {
            throw new CustomerException(ServerCode.SAME_PORT);
        }
        if (IpUtils.isLocalPortUsing(port)) {
            throw new CustomerException(ServerCode.HAS_BINDED);
        }
    }
}
